package main

import (
	"fmt"
	"hong/uniapp_server/common/config"
	"hong/uniapp_server/common/utils"
	"hong/uniapp_server/infrstructure/dao"
	"hong/uniapp_server/resources"
	"runtime/debug"
	"time"

	"github.com/goccy/go-json"
	"github.com/gofiber/fiber/v2"
	"github.com/rs/zerolog/log"
)

func main() {
	config.InitZeroLog()
	yaml := resources.GetYamlConfig()
	// 初始化MySQL
	if err := dao.InitMySql(yaml.Mysql); err != nil {
		log.Fatal().Msgf("InitMySql error %v", err)
	}
	dependencyInjection()

	app := fiber.New(fiber.Config{
		AppName:           "Uniapp Server Demo",
		BodyLimit:         10 * 1024 * 1024, // 10MB
		IdleTimeout:       30 * time.Second,
		ReadTimeout:       700 * time.Millisecond,
		JSONEncoder:       utils.JSONMarshal,
		JSONDecoder:       json.Unmarshal,
		StreamRequestBody: false,
	})
	router(app)
	app.Listen(":8080")
}

func router(app *fiber.App) {
	app.Use(apiFilter)
	app.Get("/", func(c *fiber.Ctx) error {
		return c.SendString("Hello, Uniapp Server 👋!")
	})

	app.Post("/log", recoverHandler(logController.Log))
	app.Post("/diary/add", recoverHandler(diaryController.AddDiary))
	app.Post("/diary/upload_img", recoverHandler(diaryController.UploadImg))
	app.Post("/auth/login", recoverHandler(authController.Login))
}

func recoverHandler(handler fiber.Handler) fiber.Handler {
	return func(c *fiber.Ctx) error {
		defer func() {
			if r := recover(); r != nil {
				errMsg := fmt.Sprintf("panic: %s", debug.Stack())
				log.Error().Msg(errMsg)
				_ = c.Status(fiber.StatusInternalServerError).SendString("Internal Server Error")
			}
		}()
		return handler(c)
	}
}

func apiFilter(c *fiber.Ctx) error {
	requestTime := time.Now()
	requestUrl := fmt.Sprintf("%s%s", c.BaseURL(), c.OriginalURL())
	clientIP := utils.GetRequestIp(c)
	log.Info().Msgf("%s, [%s], action: %s", requestTime.Format("2006-01-02 15:04:05"), clientIP, requestUrl)

	// actionName := c.Path()
	// needAuth := strings.HasPrefix(actionName, "/user/")
	// if needAuth {
	// 	token := c.Get("Authorization")
	// 	if token == "" {
	// 		return c.JSON(models.Response{
	// 			Code:    models.ResponseAuthError,
	// 			Message: "token error",
	// 		})
	// 	}
	// 	// remove Bearer
	// 	token = token[7:]
	// 	if err := authorizationService.ValidateToken(token); err != nil {
	// 		log.Warn().Err(err).Msgf("refresh token error %v", err)
	// 		return c.JSON(models.Response{
	// 			Code:    models.ResponseAuthError,
	// 			Message: "token error",
	// 		})
	// 	}
	// }

	return c.Next()
}
